/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.rbac.service.personconstructor.impl;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.je.common.base.DynaBean;
import com.je.common.base.mapper.query.Query;
import com.je.common.base.mvc.BaseMethodArgument;
import com.je.common.base.result.BaseRespResult;
import com.je.common.base.service.CommonService;
import com.je.common.base.service.MetaResourceService;
import com.je.common.base.service.MetaService;
import com.je.common.base.service.rpc.BeanService;
import com.je.common.base.util.SecurityUserHolder;
import com.je.common.base.util.StringUtil;
import com.je.common.base.util.TreeUtil;
import com.je.core.entity.extjs.JSONTreeNode;
import com.je.ibatis.extension.conditions.ConditionsWrapper;
import com.je.rbac.service.IconType;
import com.je.rbac.service.company.RbacDepartmentService;
import com.je.rbac.service.grant.role.RbacGrantRoleService;
import com.je.rbac.service.personconstructor.PersonConstructorService;
import com.je.rbac.util.HypyUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @ClassName
 * @Author wangchao
 * @Date 2022/6/14 0014 11:36
 * @Version V1.0
 */
@Service
public class PersonConstructorServiceImpl implements PersonConstructorService {

    private static final Logger logger = LoggerFactory.getLogger(PersonConstructorServiceImpl.class);

    @Autowired
    private BeanService beanService;

    @Autowired
    private MetaResourceService metaResourceService;

    @Autowired
    private MetaService metaService;

    @Autowired
    private CommonService commonService;

    @Autowired
    private RbacGrantRoleService rbacGrantRoleService;

    @Autowired
    private RbacDepartmentService rbacDepartmentService;


    /**
     * 构建类型：常用人员
     */
    private final String COMMON_USER = "commonUser";
    /**
     * 构建类型：部门人员
     */
    private final String DEPT_USER = "deptUser";
    /**
     * 构建类型：角色
     */
    private final String ROLE_USER = "roleUser";
    /**
     * 构建类型：机构
     */
    private final String ORG_USER = "orgUser";
    /**
     * 回显传值类型：按人员
     */
    private final String USER = "user";
    /**
     * 回显传值类型：按人员，部门
     */
    private final String USER_DEPT = "userDept";
    /**
     * 回显传值类型：按账号部门
     */
    private final String ACCOUNT_DEPT = "accountDept";

    /**
     * 限定常用人员数量
     */
    private int count = 50;

    @Override
    public void addCommonUser(String accountDeptIds) {
        //要添加的人,
        String[] idsArray = accountDeptIds.split(",");
        List<String> addList = Stream.of(idsArray).collect(Collectors.toList());

        String loginUserId = SecurityUserHolder.getCurrentAccountRealUserId();
        String realOrgId = SecurityUserHolder.getCurrentAccountDepartment().getId();
        //常用中的人
        List<String> commonList = Lists.newLinkedList();
        // 获取常用人中所有的id
        String whereSql = " AND JE_RBAC_USER_ID = '" + loginUserId + "' AND JE_RBAC_DEPT_ID = '" + realOrgId + "' ORDER BY LATESTUSER_COUNT DESC,SY_CREATETIME DESC";
        List<DynaBean> dynaBeanList = metaService.select("JE_RBAC_LATESTUSER", ConditionsWrapper.builder().apply(whereSql));
        for (DynaBean bean : dynaBeanList) {
            commonList.add(bean.getStr("JE_RBAC_ACCOUNTDEPT_ID"));
        }
        //获取相同的人的集合id
        List<String> theSameList = getTheSameSection(commonList, addList, true);
        // 给相同人的数量加1
        metaService.executeSql(" UPDATE JE_RBAC_LATESTUSER SET LATESTUSER_COUNT = LATESTUSER_COUNT+1 WHERE JE_RBAC_ACCOUNTDEPT_ID in (" + StringUtil.buildArrayToString(theSameList) + ")  AND JE_RBAC_USER_ID = '" + loginUserId + "' AND JE_RBAC_DEPT_ID = '" + realOrgId + "'");
        // 不同人的集合id
        List<String> defferentList = getTheSameSection(commonList, addList, false);
        // 添加常用人信息
        for (String deptUserId : defferentList) {
            DynaBean dynaBean = new DynaBean("JE_RBAC_LATESTUSER", false);
            dynaBean.set("JE_RBAC_ACCOUNTDEPT_ID", deptUserId);
            dynaBean.set("LATESTUSER_COUNT", 1);
            dynaBean.set("JE_RBAC_USER_ID", loginUserId);
            dynaBean.set("JE_RBAC_DEPT_ID", realOrgId);
            commonService.buildModelCreateInfo(dynaBean);
            metaService.insert(dynaBean);
        }


        // 获取添加后常用人中所有的id
        List<DynaBean> afterAddBeanList = metaService.select("JE_RBAC_LATESTUSER", ConditionsWrapper.builder().apply(whereSql));
        // 获取添加后所有人员部门id
        LinkedList<String> afterAddList = Lists.newLinkedList();
        for (DynaBean bean : afterAddBeanList) {
            afterAddList.add(bean.getStr("JE_RBAC_ACCOUNTDEPT_ID"));
        }

        if (afterAddList.size() > count) {
            int delCout = afterAddList.size() - count;
            //获取要删除的id 集合
            List<String> delIdList = getDelList(delCout, afterAddList);
            metaService.delete("JE_RBAC_LATESTUSER", ConditionsWrapper.builder().apply(" AND JE_RBAC_ACCOUNTDEPT_ID in (" + StringUtil.buildArrayToString(delIdList) + ") AND JE_RBAC_USER_ID = '" + loginUserId + "' AND JE_RBAC_DEPT_ID = '" + realOrgId + "'"));
        }

    }

    /**
     * 获取两个集合中 相同元素和不同元素的集合
     *
     * @param list1 包含集合元素
     * @param list2 被包含集合元素
     * @param flag  如果为true的话返回相同元素  false 返回不同元素
     * @return
     */
    private List getTheSameSection(List<String> list1, List<String> list2, Boolean flag) {
        List theSameList = new ArrayList();
        List diferentList = new ArrayList();
        for (String item : list2) {//遍历list2
            if (list1.contains(item)) {//如果存在这个数
                theSameList.add(item);//放进一个list里面，这个list就是交集
            } else {
                diferentList.add(item);
            }
        }
        if (flag) {
            return theSameList;
        }
        return diferentList;
    }

    /**
     * 获取list 中后几位的值
     *
     * @param i          要查询后几位的key
     * @param LinkedList 集合
     * @return
     */
    private List getDelList(int i, List<String> LinkedList) {
        ArrayList<String> list = Lists.newArrayList();
        for (int k = 0; k < i; k++) {
            list.add(LinkedList.get(LinkedList.size() - k - 1));
        }
        return list;
    }

    @Override
    public JSONTreeNode loadPersonInfo(String type, String showDeveloper, BaseMethodArgument param) {

        if (COMMON_USER.equals(type)) {
            return buildCommonAccount();
        } else if (DEPT_USER.equals(type)) {
            return buildCompanyDepartmentUserTree(false, param);
        } else if (ROLE_USER.equals(type)) {
            return buildRoleAccountTree(param);
        } else if (ORG_USER.equals(type)) {
            return buildOrgAccountTree(showDeveloper, param);
        }
        return null;
    }

    public JSONTreeNode buildCommonAccount() {
        //构建Root节点信息
        JSONTreeNode rootNode = TreeUtil.buildRootNode();

        //当前线程人员，部门信息
        String realUserId = SecurityUserHolder.getCurrentAccountRealUserId();
        String realOrgId = SecurityUserHolder.getCurrentAccountDepartment().getId();
        //获取常用人员表中数据集合
        String whereSql = " AND JE_RBAC_USER_ID = '" + realUserId + "' AND JE_RBAC_DEPT_ID = '" + realOrgId + "' GROUP BY JE_RBAC_ACCOUNTDEPT_ID ORDER BY LATESTUSER_COUNT DESC,SY_CREATETIME DESC";
        List<DynaBean> commonBeanList = metaService.select("JE_RBAC_LATESTUSER", ConditionsWrapper.builder().apply(whereSql));
        if (null == commonBeanList || commonBeanList.size() <= 0) {
            return rootNode;
        }
        for (DynaBean commonBean : commonBeanList) {
            String accountDeptId = commonBean.getStr("JE_RBAC_ACCOUNTDEPT_ID");
            DynaBean accountDeptDynaBean = metaService.selectOne("JE_RBAC_VUSERQUERY", ConditionsWrapper.builder().eq("JE_RBAC_ACCOUNTDEPT_ID", accountDeptId).eq("USER_STATUS", "1"));
            if (accountDeptDynaBean == null) {
                continue;
            }
            JSONTreeNode node = new JSONTreeNode();
            node.setId(accountDeptDynaBean.getStr("JE_RBAC_ACCOUNTDEPT_ID"));
            node.setCode(accountDeptDynaBean.getStr("USER_CODE"));
            node.setText(accountDeptDynaBean.getStr("USER_NAME"));

            node.setNodeType("LEAF");
            node.setNodeInfo(accountDeptDynaBean.getStr("USER_CODE"));
            node.setNodeInfoType("user");
            node.setIcon(IconType.TCONTYPE_ROLE.getVal());
            node.setParent(rootNode.getId());
            node.setChecked(false);
            node.setLayer(rootNode.getLayer() + 1);
            HashMap<String, Object> bean = accountDeptDynaBean.getValues();
            bean.put("pinyin", HypyUtil.getPinYin(node.getText()));
            node.setBean(bean);
            rootNode.getChildren().add(node);
        }
        return rootNode;
    }


    public JSONTreeNode buildCompanyDepartmentUserTree(Boolean multiple, BaseMethodArgument param, String... companyIds) {
        //获取公司部门树
        JSONTreeNode companyNode = rbacDepartmentService.buildCompanyTreeDataByQuery(false, param);
        List<DynaBean> departmentUserBeanList;
        if (companyIds == null || companyIds.length <= 0) {
            departmentUserBeanList = metaService.select("JE_RBAC_VUSERQUERY", ConditionsWrapper.builder().eq("USER_STATUS", "1").orderByAsc("SY_ORDERINDEX"));
        } else {
            departmentUserBeanList = metaService.select("JE_RBAC_VUSERQUERY", ConditionsWrapper.builder().in("SY_COMPANY_ID", companyIds).eq("USER_STATUS", "1").orderByAsc("SY_ORDERINDEX"));
        }

        recursiveDepartmentUserTreeNode(companyNode, departmentUserBeanList, multiple);
        return companyNode;
    }

    private void recursiveDepartmentUserTreeNode(JSONTreeNode rootNode, List<DynaBean> departmentUserBeanList, Boolean multiple) {
        if ("department".equals(rootNode.getNodeInfoType())) {
            JSONTreeNode node;
            for (DynaBean eachDepartmentUserBean : departmentUserBeanList) {
                eachDepartmentUserBean.put("DEPARTMENT_ICON", IconType.TCONTYPE_ROLE.getVal());
                if (!rootNode.getId().equals(eachDepartmentUserBean.getStr("DEPARTMENT_ID"))) {
                    continue;
                }
                node = new JSONTreeNode();
                node.setId(eachDepartmentUserBean.getStr("JE_RBAC_ACCOUNTDEPT_ID"));
                node.setCode(eachDepartmentUserBean.getStr("USER_CODE"));
                node.setText(eachDepartmentUserBean.getStr("USER_NAME"));

                node.setNodeType("LEAF");
                node.setNodeInfo(eachDepartmentUserBean.getStr("ACCOUNT_CODE"));
                node.setNodeInfoType("user");
                node.setIcon(eachDepartmentUserBean.getStr("DEPARTMENT_ICON"));
                node.setParent(rootNode.getId());
                node.setChecked(multiple);
                node.setLayer(rootNode.getLayer() + 1);
                HashMap<String, Object> bean = eachDepartmentUserBean.getValues();
                bean.put("pinyin", HypyUtil.getPinYin(node.getText()));
                node.setBean(bean);
                rootNode.getChildren().add(node);
            }
        }

        if (rootNode.getChildren() == null || rootNode.getChildren().isEmpty()) {
            return;
        }

        for (JSONTreeNode eachChildNode : rootNode.getChildren()) {
            recursiveDepartmentUserTreeNode(eachChildNode, departmentUserBeanList, multiple);
        }

    }

    public JSONTreeNode buildRoleAccountTree(BaseMethodArgument param) {
        //获取角色树
        JSONTreeNode jsonTreeNode = rbacGrantRoleService.buildRoleTreeByQuery(false, param);

        List<DynaBean> accountRoleBeanList = metaService.select("JE_RBAC_VACCOUNTROLE", ConditionsWrapper.builder());
        recursiveAccountRoleTreeNode(jsonTreeNode, accountRoleBeanList, false);
        return jsonTreeNode;
    }

    private void recursiveAccountRoleTreeNode(JSONTreeNode rootNode, List<DynaBean> accountRoleBeanList, Boolean multiple) {
        if ("role".equals(rootNode.getNodeInfoType())) {
            JSONTreeNode node;
            for (DynaBean accountRoleBean : accountRoleBeanList) {
                if (!rootNode.getId().equals(accountRoleBean.getStr("ACCOUNTROLE_ROLE_ID"))) {
                    continue;
                }
                DynaBean accountUserBean = metaService.selectOne("JE_RBAC_VUSERQUERY", ConditionsWrapper.builder().eq("USER_ID", accountRoleBean.getStr("USER_ASSOCIATION_ID")).eq("DEPARTMENT_ID", accountRoleBean.getStr("ACCOUNTROLE_DEPT_ID")).eq("USER_STATUS", "1"));
                if (accountUserBean == null || accountUserBean.getStr("JE_RBAC_ACCOUNTDEPT_ID") == null) {
                    continue;
                }
                node = new JSONTreeNode();
                node.setId(accountUserBean.getStr("JE_RBAC_ACCOUNTDEPT_ID") + "-" + accountRoleBean.getStr("JE_RBAC_ACCOUNTROLE_ID"));
                node.setCode(accountUserBean.getStr("USER_CODE"));
                node.setText(accountUserBean.getStr("USER_NAME"));

                node.setNodeType("LEAF");
                node.setNodeInfo(accountUserBean.getStr("USER_CODE"));
                node.setNodeInfoType("user");
                node.setIcon(IconType.TCONTYPE_ROLE.getVal());
                node.setParent(rootNode.getId());
                node.setChecked(multiple);
                node.setLayer(rootNode.getLayer() + 1);
                HashMap<String, Object> bean = accountUserBean.getValues();
                bean.put("pinyin", HypyUtil.getPinYin(node.getText()));
                node.setBean(bean);
                rootNode.getChildren().add(node);
            }
        }

        if (rootNode.getChildren() == null || rootNode.getChildren().isEmpty()) {
            return;
        }

        for (JSONTreeNode eachChildNode : rootNode.getChildren()) {
            recursiveAccountRoleTreeNode(eachChildNode, accountRoleBeanList, multiple);
        }

    }

    public JSONTreeNode buildOrgAccountTree(String showDeveloper, BaseMethodArgument param) {
        Query query = param.buildQuery();
        ConditionsWrapper conditionsWrapper = query.buildWrapper();

        //构建组织树
        JSONTreeNode rootNode = TreeUtil.buildRootNode();
        List<DynaBean> orgListBean = null;
        //过滤 公司部门 开发者机构
        //showDeveloper == '1'  就有开发者机构,  默认是没有的
        String parameterSql = conditionsWrapper.getParameterSql();
        boolean isShow = parameterSql.contains("showDeveloper");
        if ((!Strings.isNullOrEmpty(showDeveloper) && "1".equals(showDeveloper)) || isShow) {
            orgListBean = metaService.select("JE_RBAC_ORG", ConditionsWrapper.builder().ne("ORG_CODE", "department").ne("SY_STATUS", "0").orderByDesc("SY_CREATETIME"));
        } else {
            orgListBean = metaService.select("JE_RBAC_ORG", conditionsWrapper.ne("ORG_CODE", "department").ne("SY_STATUS", "0").ne("ORG_CODE", "develop").orderByDesc("SY_CREATETIME"));
        }
        if (null == orgListBean) {
            return rootNode;
        }
        for (DynaBean eachBean : orgListBean) {
            JSONTreeNode node = new JSONTreeNode();
            node.setId(eachBean.getStr("JE_RBAC_ORG_ID"));
            node.setCode(eachBean.getStr("ORG_CODE"));
            node.setText(eachBean.getStr("ORG_NAME"));
            node.setNodeType("LEAF");
            node.setNodeInfo(eachBean.getStr("ORG_CODE"));
            node.setNodeInfoType("org");
            node.setIcon(IconType.TCONTYPE_ORG.getVal());
            node.setParent(rootNode.getId());
            node.setChecked(false);
            node.setLayer(rootNode.getLayer() + 1);
            node.setBean(eachBean.getValues());
            rootNode.getChildren().add(node);
        }

        List<DynaBean> accountOrgBeanList = metaService.select("JE_RBAC_VUSERQUERY", ConditionsWrapper.builder().eq("USER_STATUS", "1"));
        recursiveAccountOrgTreeNode(rootNode, accountOrgBeanList, false);
        return rootNode;
    }

    private void recursiveAccountOrgTreeNode(JSONTreeNode rootNode, List<DynaBean> accountOrgBeanList, Boolean
            multiple) {
        if ("org".equals(rootNode.getNodeInfoType())) {
            JSONTreeNode node;
            for (DynaBean eachAccountOrgBean : accountOrgBeanList) {
                if (!rootNode.getId().equals(eachAccountOrgBean.getStr("SY_ORG_ID"))) {
                    continue;
                }
                node = new JSONTreeNode();
                node.setId(eachAccountOrgBean.getStr("JE_RBAC_ACCOUNTDEPT_ID"));
                node.setCode(eachAccountOrgBean.getStr("USER_CODE"));
                node.setText(eachAccountOrgBean.getStr("USER_NAME"));

                node.setNodeType("LEAF");
                node.setNodeInfo(eachAccountOrgBean.getStr("USER_CODE"));
                node.setNodeInfoType("user");
                node.setIcon(IconType.TCONTYPE_ROLE.getVal());
                node.setParent(rootNode.getId());
                node.setChecked(multiple);
                node.setLayer(rootNode.getLayer() + 1);
                HashMap<String, Object> bean = eachAccountOrgBean.getValues();
                bean.put("pinyin", HypyUtil.getPinYin(node.getText()));
                node.setBean(bean);
                rootNode.getChildren().add(node);
            }
        }

        if (rootNode.getChildren() == null || rootNode.getChildren().isEmpty()) {
            return;
        }

        for (JSONTreeNode eachChildNode : rootNode.getChildren()) {
            recursiveAccountOrgTreeNode(eachChildNode, accountOrgBeanList, multiple);
        }

    }

    @Override
    public BaseRespResult getPersonInfoEcho(String type, JSONArray parseArray) {
        List<Map<String, Object>> resultBean = Lists.newLinkedList();
        Map<String, Object> map = null;
        //按不同类型构建查询条件
        if (USER.equals(type)) {
            LinkedList<String> list = new LinkedList<>();
            for (int i = 0; i < parseArray.size(); i++) {
                JSONObject jsonObject = parseArray.getJSONObject(i);
                String userId = jsonObject.getString("userId");
                if (StringUtil.isEmpty(userId)) {
                    continue;
                }
                if (list.contains(userId)) {
                    continue;
                }
                list.add(userId);
            }
            for (String userId : list) {
                List<DynaBean> dynaBean = metaService.select("JE_RBAC_VUSERQUERY", ConditionsWrapper.builder().eq("USER_ID", userId).eq("USER_STATUS", "1"));
                if (dynaBean == null || dynaBean.size() <= 0) {
                    continue;
                }
                map = new LinkedHashMap();
                map.put("id", dynaBean.get(0).getStr("JE_RBAC_ACCOUNTDEPT_ID"));
                map.put("code", dynaBean.get(0).getStr("USER_CODE"));
                map.put("text", dynaBean.get(0).getStr("USER_NAME"));
                map.put("bean", dynaBean.get(0).getValues());
                resultBean.add(map);
            }
            return BaseRespResult.successResult(resultBean);
        } else if (USER_DEPT.equals(type)) {
            LinkedList<String> list = new LinkedList<>();
            for (int i = 0; i < parseArray.size(); i++) {
                JSONObject jsonObject = parseArray.getJSONObject(i);
                String userId = jsonObject.getString("userId");
                String deptId = jsonObject.getString("deptId");
                if (StringUtil.isEmpty(userId) && StringUtil.isEmpty(deptId)) {
                    continue;
                }
                if (list.contains(userId + "_" + deptId)) {
                    continue;
                }
                list.add(userId + "_" + deptId);
            }
            for (String userDeptIds : list) {
                String[] userDeptId = userDeptIds.split("_");
                if (userDeptId.length < 1) {
                    continue;
                }
                DynaBean accountOrgBean = metaService.selectOne("JE_RBAC_VUSERQUERY", ConditionsWrapper.builder().eq("USER_ID", userDeptIds.split("_")[0]).eq("DEPARTMENT_ID", userDeptIds.split("_")[1]).eq("USER_STATUS", "1"));
                if (accountOrgBean == null) {
                    continue;
                }
                map = new LinkedHashMap();
                map.put("id", accountOrgBean.getStr("JE_RBAC_ACCOUNTDEPT_ID"));
                map.put("code", accountOrgBean.getStr("USER_CODE"));
                map.put("text", accountOrgBean.getStr("USER_NAME"));
                map.put("bean", accountOrgBean.getValues());
                resultBean.add(map);
            }
            return BaseRespResult.successResult(resultBean);
        } else if (ACCOUNT_DEPT.equals(type)) {
            LinkedList<String> list = new LinkedList<>();
            for (int i = 0; i < parseArray.size(); i++) {
                JSONObject jsonObject = parseArray.getJSONObject(i);
                String accountDeptId = jsonObject.getString("accountDeptId");
                if (StringUtil.isEmpty(accountDeptId)) {
                    continue;
                }
                if (list.contains(accountDeptId)) {
                    continue;
                }
                list.add(accountDeptId);
            }
            for (String accountDeptId : list) {
                DynaBean accountOrgBean = metaService.selectOne("JE_RBAC_VUSERQUERY", ConditionsWrapper.builder().eq("JE_RBAC_ACCOUNTDEPT_ID", accountDeptId).eq("USER_STATUS", "1"));
                if (accountOrgBean == null) {
                    continue;
                }
                map = new LinkedHashMap();
                map.put("id", accountOrgBean.getStr("JE_RBAC_ACCOUNTDEPT_ID"));
                map.put("code", accountOrgBean.getStr("USER_CODE"));
                map.put("text", accountOrgBean.getStr("USER_NAME"));

                map.put("bean", accountOrgBean.getValues());
                resultBean.add(map);
            }
            return BaseRespResult.successResult(resultBean);
        }
        return BaseRespResult.errorResult("传入类型错误！");
    }

}
